/*
 * Copyright (c) 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.libermundi.theorcs.core.tapestry.model;

import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Map;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.apache.tapestry5.ioc.Messages;
import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.services.AssetFactory;
import org.libermundi.theorcs.core.CoreConstants;
import org.libermundi.theorcs.core.exceptions.EmailException;
import org.libermundi.theorcs.core.model.freemarker.EmailMimeTemplate;
import org.libermundi.theorcs.core.model.freemarker.FreemarkerEmail;
import org.libermundi.theorcs.core.tapestry.services.FreeMarkerService;
import org.libermundi.theorcs.core.tapestry.services.configuration.ApplicationConfig;
import org.springframework.mail.javamail.MimeMessageHelper;

import com.google.common.collect.Maps;

/**
 * @author Martin Papy
 *
 */
public abstract class AbstractFreemarkerEmail extends AbstractEmail implements FreemarkerEmail {
	private static final long serialVersionUID = -1489487833038138253L;
	
	private final FreeMarkerService _freeMarkerService;

	private final AssetFactory _assetFactory;
	
	private EmailMimeTemplate _template;
	
	private final Messages _messages;
	
	/**
	 * @param appConfig
	 * @param freeMarkerService
	 * @param resourceLocator
	 */
	public AbstractFreemarkerEmail(ApplicationConfig appConfig, FreeMarkerService freeMarkerService, AssetFactory assetFactory, Messages messages) {
		super(appConfig);
		_freeMarkerService = freeMarkerService;
		_assetFactory = assetFactory;
		_messages = messages;
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.libermundi.theorcs.core.model.freemarker.FreemarkerEmail#getMailMessage(javax.mail.internet.MimeMessage, java.util.Map)
	 */
	@Override
	public MimeMessageHelper getMailMessage(MimeMessage mimeMessage, Map<String, Object> parameters) throws EmailException {
		MimeMessageHelper message = getDefaultMimeMessageHelper(mimeMessage);
		
		//first Let's check if the Parameters are Ok.
		getTemplate().checkConsistency(parameters);
		
		Map<String, Object> finalParam = Maps.newHashMap(getTemplate().getOptionnalParams());
		finalParam.putAll(parameters);
		
		try {
			// Set the Title
			message.setSubject(getTitle());
			
			//Text Part of the Email
			Resource txtTemplate = getAssetFactory().getRootResource().forFile(getTemplate().getTemplatePath());
			ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
			getFreeMarkerService().mergeDataWithResource(txtTemplate, outputStream, finalParam);
			message.setText(outputStream.toString(CoreConstants.CHARACTER_ENCODING));
	
			//HTML Part of the Email
			Resource htmlTemplate = getAssetFactory().getRootResource().forFile(getTemplate().getHtmlTemplatePath());
			outputStream = new ByteArrayOutputStream();
			getFreeMarkerService().mergeDataWithResource(htmlTemplate, outputStream, finalParam);
			message.setText(outputStream.toString(CoreConstants.CHARACTER_ENCODING),Boolean.TRUE);
			
		} catch (UnsupportedEncodingException | MessagingException e) {
			throw new EmailException(e.getMessage());
		}
		
		return message;

	}	
	
	protected FreeMarkerService getFreeMarkerService(){
		return _freeMarkerService;
	}

	protected AssetFactory getAssetFactory(){
		return _assetFactory;
	}

	/**
	 * @return the template
	 */
	protected EmailMimeTemplate getTemplate() {
		return _template;
	}

	/**
	 * @param template the template to set
	 */
	protected void setTemplate(EmailMimeTemplate template) {
		_template = template;
	}
	
	/**
	 * @return the {@link Messages}
	 */
	protected Messages getMessages() {
		return _messages;
	}
	
	protected abstract String getTitle();
}
